package com.cash.app.ui.auth

import android.content.Context
import android.net.Uri
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.cash.app.base.BaseViewModel
import com.cash.app.constant.AppConstant.AUTH_TYPE_BASIC
import com.cash.app.net.NetRequestExecutor
import com.cash.app.net.RetrofitClient
import com.cash.app.ui.auth.api.AuthAPIService
import com.cash.app.ui.auth.model.AuthBaseInfoResponse
import com.cash.app.ui.auth.model.AuthTypeRequest
import com.cash.app.ui.auth.model.OcrACardBackResponse
import com.cash.app.ui.auth.model.OcrACardFrontResponse
import com.cash.app.ui.auth.model.OcrPCardFrontResponse
import com.cash.app.ui.auth.model.OcrRequest
import com.cash.app.ui.auth.model.StepOneRequest
import com.cash.app.utils.ImageBase64Utils
import com.cash.app.utils.getGenderInt
import kotlinx.coroutines.launch

class AuthBasicViewModel : BaseViewModel() {
    private val authAPIService by lazy {
        RetrofitClient.createService(AuthAPIService::class.java)
    }

    private val _authBaseInfo = MutableLiveData<AuthBaseInfoResponse>()
    val authBaseInfo: LiveData<AuthBaseInfoResponse> = _authBaseInfo

    private val _submitSuccess = MutableLiveData<Boolean>()
    val submitSuccess: LiveData<Boolean> = _submitSuccess

    private val _ocrACardFrontInfo = MutableLiveData<OcrACardFrontResponse>()
    val ocrACardFrontInfo: LiveData<OcrACardFrontResponse> = _ocrACardFrontInfo

    private val _ocrACardBackInfo = MutableLiveData<OcrACardBackResponse>()
    val ocrACardBackInfo: LiveData<OcrACardBackResponse> = _ocrACardBackInfo

    private val _ocrPCardFrontInfo = MutableLiveData<OcrPCardFrontResponse>()
    val ocrPCardFrontInfo: LiveData<OcrPCardFrontResponse> = _ocrPCardFrontInfo

    private val _imageBase64 = MutableLiveData<Pair<Int, List<String>>>()
    val imageBase64: LiveData<Pair<Int, List<String>>> = _imageBase64

    private val _isLoading = MutableLiveData<Boolean>()
    val isLoading: LiveData<Boolean> = _isLoading

    private val _aFrontOcrStatus = MutableLiveData<Boolean>()
    val aFrontOcrStatus: LiveData<Boolean> = _aFrontOcrStatus

    private val _aBackOcrStatus = MutableLiveData<Boolean>()
    val aBackOcrStatus: LiveData<Boolean> = _aBackOcrStatus

    private val _pFrontOcrStatus = MutableLiveData<Boolean>()
    val pFontOcrStatus: LiveData<Boolean> = _pFrontOcrStatus

    fun processImageBase64(context: Context, uri: Uri, imgType: Int) {
        viewModelScope.launch {
            try {
                _isLoading.value = true
                val base64String = ImageBase64Utils.convertImagesToBase64(context, listOf(uri))
                _imageBase64.value = Pair(imgType, base64String)
            } catch (e: Exception) {
                e.printStackTrace()
                _isLoading.value = false
            }
        }
    }

    fun getAuthInfoByBasic() {
        launchRequest(request = {
            NetRequestExecutor.baseNetRequest {
                authAPIService.getAuthInfoByBase(AuthTypeRequest(authType = AUTH_TYPE_BASIC))
            }
        }, onSuccess = { response ->
            response?.let {
                _authBaseInfo.value = it
            }
        })
    }

    fun getOcrByACardFront(cardImgBase64: String, imgType: Int) {
        launchRequest(request = {
            NetRequestExecutor.baseNetRequest {
                authAPIService.getOcrByACardFront(
                    OcrRequest(
                        cardImg = cardImgBase64, imgType = imgType
                    )
                )
            }
        }, onSuccess = { response ->
            response?.let {
                _ocrACardFrontInfo.value = it
            }
            _isLoading.value = false
            _aFrontOcrStatus.value = true
        }, onError = { _, _ ->
            _isLoading.value = false
            _aFrontOcrStatus.value = false
        })
    }

    fun getOcrByACardBack(cardImgBase64: String, imgType: Int) {
        launchRequest(request = {
            NetRequestExecutor.baseNetRequest {
                authAPIService.getOcrByACardBack(
                    OcrRequest(
                        cardImg = cardImgBase64, imgType = imgType
                    )
                )
            }
        }, onSuccess = { response ->
            response?.let {
                _ocrACardBackInfo.value = it
            }
            _isLoading.value = false
            _aBackOcrStatus.value = true
        }, onError = { _, _ ->
            _isLoading.value = false
            _aBackOcrStatus.value = false
        })
    }

    fun getOcrByPCardFront(cardImgBase64: String, imgType: Int) {
        launchRequest(request = {
            NetRequestExecutor.baseNetRequest {
                authAPIService.getOcrByPCardFront(
                    OcrRequest(
                        cardImg = cardImgBase64, imgType = imgType
                    )
                )
            }
        }, onSuccess = { response ->
            response?.let {
                _ocrPCardFrontInfo.value = it
            }
            _isLoading.value = false
            _pFrontOcrStatus.value = true
        }, onError = { _, _ ->
            _isLoading.value = false
            _pFrontOcrStatus.value = false
        })
    }

    fun submitStepOne(
        selfieBase64: String
    ) {
        _isLoading.value = true
        val request = StepOneRequest(
            headImg = selfieBase64,
            // A card front
            adFrontUrl = ocrACardFrontInfo.value!!.cardImg,
            adNumber = ocrACardFrontInfo.value!!.cardInfo.values.idNumber,
            userName = ocrACardFrontInfo.value!!.cardInfo.values.name,
            gender = ocrACardFrontInfo.value!!.cardInfo.values.gender.getGenderInt(),

            // pan card
            panFrontUrl = ocrPCardFrontInfo.value!!.cardImg,
            panNumber = ocrPCardFrontInfo.value!!.cardInfo.values.idNumber,
            birth = ocrPCardFrontInfo.value!!.cardInfo.values.birthday,
            father = ocrPCardFrontInfo.value!!.cardInfo.values.fatherName,
            // A card back
            adBackUrl = ocrACardBackInfo.value!!.cardImg,
            adState = ocrACardBackInfo.value!!.cardInfo.values.state,
            adDistrict = ocrACardBackInfo.value!!.cardInfo.values.district,
            adAddress = ocrACardBackInfo.value!!.cardInfo.values.addressAll,
            adPincode = ocrACardBackInfo.value!!.cardInfo.values.pin,
        )
        launchRequest(request = {
            NetRequestExecutor.baseNetRequest {
                authAPIService.submitStepOne(request)
            }
        }, onSuccess = { response -> // rsp is empty
            _isLoading.value = false
            _submitSuccess.value = true
        }, onError = { _, _ ->
            _isLoading.value = false
            _submitSuccess.value = false
        })
    }
} 